define(function(require, exports, module) {

  // var Backbone = require('backbone');
  var $ = require('jquery');
  var _ = require('underscore');
  // var jsonview = require('jsonview');
  var tmpl = require('text!../tmpl.html');

  require([
    'css!/assets/lib/animate/animate.css',
    'css!hy5b/animation/control.css'
  ])

  require('hy5b/frontend/canvas/line')
  // require('hy5b/frontend/canvas/hline')
  
  var animation = require('hy5b/animation/index')
  var control = require('hy5b/animation/control')

  //先手为源，后手为目标
  var compositeOperations = [
    'source-over', 
    'source-in',
    'source-out',
    'source-atop',
    'destination-over',
    'destination-in',
    'destination-out',
    'destination-atop',
    'lighter',
    'copy',
    'xor',
    'multiply',
    'screen',
    'overlay',
    'darken',
    'lighten',
    'color-dodge',
    'color-burn',
    'hard-light',
    'soft-light',
    'difference',
    'exclusion',
    'hue',
    'saturation',
    'color',
    'luminosity'
  ]

  function main() {
    var $app = $('<div id="app">');
    $('#main').html($app);

    $app.append(tmpl);

    var $text = $('#text-animate')
    var text = $text.text()
    $text.html('')
    var time = 1000
    var textArr = text.split('')
    var delayPerWord = 1000 / textArr.length;
    var $div = $('<div>')
    for (var i = 0; i < textArr.length; i++) {
      $div.append($('<span class="animated fadeIn">').text(textArr[i]).css('animation-delay', delayPerWord * i + 'ms'));
    }
    $text.html($div.html())

    var $canvas = $('#subscribe')
    $canvas.attr('width', '800').attr('height', '30');

    var lineRenderer = getLineRenderer()
    var textRenderer = getTextRenderer()
    var trangleRenderer = getTrangleRenderer()
    var animateGlowRenderer = getAnimateGlowRenderer()

    var T = 1800; //不循环动画最大结束时间
    var dT = 1200; //循环动画周期(循环动画延迟时间小于T)
    var lineDuration = 600;
    var textDuration = 400;
    var textOpacityDuration = 500;
    var trangleDuration = dT;
    var trangleMaxOffset = 10;
    var animate = new animation({
      props: {
        lineDashOffset: {
          start: 560,
          end: 0,
          duration: lineDuration,
        },
        textOpacity: {
          start: 0,
          end: 1,
          delay: lineDuration,
          duration: textDuration
        },
        glowX: {
          start: 580,
          end: 800,
          delay: lineDuration + textDuration,
          duration: textOpacityDuration
        },
        trangleOffset: {
          start: 0,
          end: trangleMaxOffset,
          infinity: true,
          delay: lineDuration + textDuration,
          duration: trangleDuration
        }
      },
      duration: T
    })

    var staticProps = {
      x: 600
    }

    var stepType = animation.TYPE.ANIMATION_ONCE
    var isInfinity = animate.isInfinity();

// 1 isInfinity,STATIC_FRAME 
// Infinity
// 2 isInfinity,ANIMATION_ONCE 
// Infinity
// 3 isInfinity,ANIMATION_LOOP 
// Infinity
// 4 notInfinity,STATIC_FRAME  
// t=x
// STATIC_FRAME
// 5 notInfinity,ANIMATION_ONCE  
// ANIMATION_ONCE
// 6 notInfinity,ANIMATION_LOOP  
// ANIMATION_LOOP
    var t = 0
    function step() {
      if (t >= T) {
        if (isInfinity) {
          if (t >= T + dT) {
            t = T
          }
        } else {
          if (stepType === animation.TYPE.ANIMATION_LOOP) {
            t = 0
          } else {
            $canvas.clearCanvas()
            lineRenderer($canvas)
            textRenderer($canvas, 1)
            trangleRenderer($canvas)
            return;
          }
        } 
      }
      
      if (stepType === animation.TYPE.ANIMATION_ONCE || stepType === animation.TYPE.ANIMATION_LOOP) {
        requestAnimationFrame(step)
      }
      var props = animate.getStaticFrame(t)
      $canvas.clearCanvas()
      lineRenderer($canvas, props.lineDashOffset.now)
      textRenderer($canvas, props.textOpacity.now)
      if (props.trangleOffset.started) {
        var trangleOffset = props.trangleOffset.now;
        if (trangleOffset > trangleMaxOffset / 2) {
          trangleOffset = trangleMaxOffset - trangleOffset;
        }
        trangleRenderer($canvas, trangleOffset);
      }
      if (props.glowX.started) {
        animateGlowRenderer($canvas, stepType === animation.TYPE.STATIC_FRAME ? staticProps.x : props.glowX.now)
      }
      t += animation.FRAME60;
    }

    step()

    $btns = $('<div>').addClass('btn-group')
    _.each(compositeOperations, function(item) {
      $btns.append($('<button>').addClass('btn btn-primary').html(item).click(function() {
        animateGlowRenderer = getAnimateGlowRenderer({ compositeOperation: item })
        if (isInfinity) {
          t = 0;
        } else if (stepType === animation.TYPE.ANIMATION_ONCE) {
          if (t >= T) {
            t = 0;
            step();
          } else {
            t = 0;
          }
        } else if (stepType === animation.TYPE.STATIC_FRAME) {
          step()
        }
      }))
    })
    $app.append($btns)

    $app.append($('<div class="w600">').html(control()))
    
  }


  function getLineRenderer() {
    return function render($el, lineDashOffset) {
      $el.drawLine({
        strokeStyle: 'rgba(180,180,180)',
        lineWidth: 2,
        lineDash: [560],
        lineDashOffset: lineDashOffset,
        points: [[0, 15], [560, 15]]
      })
    }
  }

  function getTextRenderer() {
    return function render($el, textOpacity) {
      var p = {
        fillStyle: 'rgba(180,180,180,' + textOpacity + ')',
        x: 580, y: 15,
        font: 'bold 20px Gotham',
        textBaseline: 'middle',
        text: 'SUBSCRIBE HERE!'
      }
      if (textOpacity === 1) {
        _.extend(p, {
          strokeStyle: 'rgba(180,180,180,0.8)',
          lineWidth: 1
        })
      }
      $el.drawText(p)
    }
  }

  function getTrangleRenderer() {
    var x = 784, width = 6;
    return function render($el, offset) {
      var newX = x + (offset || 0);
      $el.drawLine({
        fillStyle: '#fefefe',
        points: [[newX, 8], [newX + width, 14], [newX, 20]]
      })
    }
  }

  function getAnimateGlowRenderer(options) {
    var width = 10, offset = 15;
    var compositeOperation = options ? options.compositeOperation : 'source-atop';

    return function render($el, x) {
      var ctx = $el[0].getContext('2d');
      ctx.save()
      ctx.beginPath();
      ctx.globalCompositeOperation = compositeOperation;
      $el.drawLine({
        acceptSave: true,
        fillStyle: '#fff',
        shadowColor: '#fff',
        shadowBlur: 5,
        points: [[x, 0], [x+width, 0], [x+width+offset, 30], [x+offset, 30]]
      })
    }
    
  }

  return main;
})
